CONST      = { "const" }
INT        = { "int" }
VOID       = { "void" }
IF         = { "if" }
ELSE       = { "else" }
WHILE      = { "while" }
BREAK      = { "break" }
CONTINUE   = { "continue" }
RETURN     = { "return" }

PLUS       = { "+" }
MINUS      = { "-" }
MUL        = { "*" }
DIV        = { "/" }
MOD        = { "%" }

ASSIGN     = { "=" }
EQ         = { "==" }
NEQ        = { "!=" }
LT         = { "<" }
GT         = { ">" }
LE         = { "<=" }
GE         = { ">=" }
NOT        = { "!" }
AND        = { "&&" }
OR         = { "||" }

L_PAREN    = { "(" }
R_PAREN    = { ")" }
L_BRACE    = { "{" }
R_BRACE    = { "}" }
L_BRACKT   = { "[" }
R_BRACKT   = { "]" }
COMMA      = { "," }
SEMICOLON  = { ";" }


IDENT      = { (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }

INTEGER_CONST = {
    ASCII_NONZERO_DIGIT ~ ASCII_DIGIT*
    | "0" ~ ASCII_OCT_DIGIT+
    | "0x" ~ ASCII_HEX_DIGIT+
    | "0X" ~ASCII_HEX_DIGIT+
    | "0"
}

WS  = _{ " " | "\r" | "\n" | "\t" }
LINE_COMMENT      = _{ "//" ~ (!"\n" ~ ANY)* ~ ("\n" | EOI) }
MULTILINE_COMMENT = _{ "/*" ~ (!"*/" ~ ANY)* ~ "*/" }

token = _{
    CONST | INT | VOID | IF | ELSE | WHILE | BREAK | RETURN | CONTINUE 
    | PLUS | MINUS | MUL | DIV | MOD | ASSIGN | EQ | NEQ | LT | GT | LE
    | GE | NOT | AND | OR | L_PAREN | R_PAREN | L_BRACE | R_BRACE 
    | L_BRACKT | R_BRACKT | COMMA | SEMICOLON | IDENT | INTEGER_CONST
}

token_list = { SOI ~ ( (WS | LINE_COMMENT | MULTILINE_COMMENT)* ~ token )* ~ (WS | LINE_COMMENT | MULTILINE_COMMENT)* }